﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Media;

namespace BuildOptimizer
{
    public partial class GUI : Form
    {
        private BoDecisionAnalyzer _analyzer = null;

        public GUI()
        {
            InitializeComponent();
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            buttonStart.Enabled = false;
            buttonCancel.Enabled = true;

            backgroundWorkerAnalyzer.RunWorkerAsync();
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            buttonStart.Enabled = true;
            buttonCancel.Enabled = false;

            _analyzer.cancelAllWork();
        }

        private void backgroundWorkerAnalyzer_DoWork(object sender, DoWorkEventArgs e)
        {
            int[] units = new int[Enum.GetNames(typeof(Units)).Length];
            int[] buildings = new int[Enum.GetNames(typeof(Buildings)).Length];
            bool[] upgrades = new bool[Enum.GetNames(typeof(Upgrades)).Length];

            units[(int)Units.Drone] = (int)numericUpDownDrones.Value;
            units[(int)Units.Overlord] = (int)numericUpDownOverlords.Value;
            units[(int)Units.Overseer] = (int)numericUpDownOverseers.Value;
            units[(int)Units.Zergling] = (int)numericUpDownZerglings.Value;
            units[(int)Units.Baneling] = (int)numericUpDownBanelings.Value;
            units[(int)Units.Roach] = (int)numericUpDownRoaches.Value;
            units[(int)Units.Mutalisk] = (int)numericUpDownMutalisks.Value;
            units[(int)Units.Infestor] = (int)numericUpDownInfestors.Value;
            units[(int)Units.Queen] = (int)numericUpDownQueens.Value;
            units[(int)Units.Hydralisk] = (int)numericUpDownHydralisks.Value;
            units[(int)Units.Corruptor] = (int)numericUpDownCorruptors.Value;
            units[(int)Units.Ultralisk] = (int)numericUpDownUltralisks.Value;
            units[(int)Units.Broodlord] = (int)numericUpDownBroodlords.Value;

            buildings[(int)Buildings.Hatchery] = (int)numericUpDownHatcheries.Value;
            buildings[(int)Buildings.Lair] = (int)numericUpDownLairs.Value;
            buildings[(int)Buildings.Hive] = (int)numericUpDownHives.Value;
            buildings[(int)Buildings.SpawningPool] = (int)numericUpDownSpawningPools.Value;
            buildings[(int)Buildings.EvolutionChamber] = (int)numericUpDownEvoChambers.Value;
            buildings[(int)Buildings.RoachWarren] = (int)numericUpDownRoachWarrens.Value;
            buildings[(int)Buildings.HydraliskDen] = (int)numericUpDownHydraliskDens.Value;
            buildings[(int)Buildings.BanelingNest] = (int)numericUpDownBanelingNests.Value;
            buildings[(int)Buildings.InfestationPit] = (int)numericUpDownInfestationPits.Value;
            buildings[(int)Buildings.GreaterSpire] = (int)numericUpDownGreaterSpires.Value;
            buildings[(int)Buildings.UltraliskCavern] = (int)numericUpDownUltraliskCaverns.Value;
            buildings[(int)Buildings.Extractor] = (int)numericUpDownExtractors.Value;
            buildings[(int)Buildings.Spire] = (int)numericUpDownSpires.Value;
            buildings[(int)Buildings.SpineCrawler] = (int)numericUpDownSpineCrawlers.Value;
            buildings[(int)Buildings.SporeCrawler] = (int)numericUpDownSporeCrawlers.Value;
            buildings[(int)Buildings.NydusNetwork] = (int)numericUpDownNydusNetworks.Value;
            buildings[(int)Buildings.NydusWorm] = (int)numericUpDownNydusWorms.Value;
            buildings[(int)Buildings.CreepTumor] = (int)numericUpDownCreepTumors.Value;

            upgrades[(int)Upgrades.MetabolicBoost] = checkMetabolicBoost.Checked;
            upgrades[(int)Upgrades.AdrenalGlands] = checkAdrenalGlands.Checked;
            upgrades[(int)Upgrades.GlialReconstitution] = checkGlialReconstitution.Checked;
            upgrades[(int)Upgrades.TunnelingClaws] = checkTunnelingClaws.Checked;
            upgrades[(int)Upgrades.Burrow] = checkBurrow.Checked;
            upgrades[(int)Upgrades.PneumatizedCarapace] = checkPneumatizedCarapace.Checked;
            upgrades[(int)Upgrades.VentralSacs] = checkVentralSacs.Checked;
            upgrades[(int)Upgrades.CentrifugalHooks] = checkCentrifugalHooks.Checked;
            upgrades[(int)Upgrades.Melee1] = checkMeleeAttacks1.Checked;
            upgrades[(int)Upgrades.Melee2] = checkMeleeAttacks2.Checked;
            upgrades[(int)Upgrades.Melee3] = checkMeleeAttacks3.Checked;
            upgrades[(int)Upgrades.Missile1] = checkMissileAttacks1.Checked;
            upgrades[(int)Upgrades.Missile2] = checkMissileAttacks2.Checked;
            upgrades[(int)Upgrades.Missile3] = checkMissileAttacks3.Checked;
            upgrades[(int)Upgrades.GroundArmor1] = checkGroundCarapace1.Checked;
            upgrades[(int)Upgrades.GroundArmor2] = checkGroundCarapace2.Checked;
            upgrades[(int)Upgrades.GroundArmor3] = checkGroundCarapace3.Checked;
            upgrades[(int)Upgrades.GroovedSpines] = checkGroovedSpines.Checked;
            upgrades[(int)Upgrades.NeuralParasite] = checkNeuralParasite.Checked;
            upgrades[(int)Upgrades.PathogenGlands] = checkPathogenGlands.Checked;
            upgrades[(int)Upgrades.flyerAttack1] = checkFlyerAttacks1.Checked;
            upgrades[(int)Upgrades.flyerAttack2] = checkFlyerAttacks2.Checked;
            upgrades[(int)Upgrades.flyerAttack3] = checkFlyerAttacks3.Checked;
            upgrades[(int)Upgrades.flyerArmor1] = checkFlyerCarapace1.Checked;
            upgrades[(int)Upgrades.flyerArmor2] = checkFlyerCarapace2.Checked;
            upgrades[(int)Upgrades.flyerArmor3] = checkFlyerCarapace3.Checked;
            upgrades[(int)Upgrades.ChitinousPlating] = checkChitinousPlating.Checked;

            int nbBases = (int)numericUpDownNbBases.Value;
            int nbThreads = (int)numericUpDownNbThreads.Value;
            int timeLimit = (int)numericUpDownTimeLimit.Value;

            BoGoal goal = new BoGoal(timeLimit, nbBases, units, buildings, upgrades);
            _analyzer = new BoDecisionAnalyzer(goal);

            _analyzer.registerGUI(this);
            _analyzer.start(nbThreads);
        }

        private void backgroundWorkerAnalyzer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            buttonStart.Enabled = true;
            buttonCancel.Enabled = false;

            SystemSounds.Asterisk.Play();
        }

        public void updateOutputText(string output)
        {
            textOutput.Text = output;

            //display the best time in title bar
            string str = "nbTicksPassed: ";
            int index0 = output.IndexOf(str);

            if (index0 != -1)
            {
                int index1 = output.IndexOf("\r\n", index0);
                int length = index1 - (index0 + str.Length);
                string bestTime = output.Substring(index0 + str.Length, length);
                this.Text = "BuildOptimizer - " + bestTime;
            }
        }
    }
}
